import {
  ControlController,
  IViewLayoutPanelController,
} from '@ibiz-template/runtime';
import { useNamespace } from '@ibiz-template/vue3-util';
import { IControlContainer } from '@ibiz/model-core';
import { defineComponent, h, PropType, resolveComponent, VNode } from 'vue';

export const IBizControlBase = defineComponent({
  name: 'IBizControlBase',
  props: {
    controller: {
      type: Object as PropType<ControlController>,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('control');
    const { controlType, sysCss, codeName } = props.controller.model;
    const typeClass = controlType!.toLowerCase();
    const sysCssName = sysCss?.cssName;

    /** 子部件模型 */
    const controls = (props.controller.model as IControlContainer).controls;

    const onLayoutPanelCreated = (
      controller: IViewLayoutPanelController,
    ): void => {
      props.controller.setLayoutPanel(controller as IViewLayoutPanelController);
    };

    return {
      ns,
      typeClass,
      sysCssName,
      codeName,
      controls,
      onLayoutPanelCreated,
    };
  },
  render() {
    const { state, controlPanel, providers } = this.controller;
    let layoutPanel = null;
    // 有部件布局的绘制布局面板
    if (state.isCreated && controlPanel) {
      // 绘制部件插槽，外部插槽优先
      const slots: IData = {
        ...this.$slots,
      };

      if (this.controls?.length) {
        this.controls.forEach(ctrl => {
          const slotKey = ctrl.name!;
          const ctrlProps = {
            context: this.controller.context,
            params: this.controller.params,
          };
          // 已经有插槽的不用自己绘制了。
          const outCtrlSlot = slots[slotKey];
          if (outCtrlSlot) {
            slots[slotKey] = (): VNode => {
              return outCtrlSlot(ctrlProps);
            };
          } else {
            slots[slotKey] = (): VNode => {
              const comp = resolveComponent('IBizControlShell') as string;
              return h(comp, {
                modelData: ctrl,
                ...ctrlProps,
              });
            };
          }
        });
      }

      // 绘制布局面板
      const provider = providers[controlPanel.name!];
      layoutPanel = h(
        resolveComponent(provider.component) as string,
        {
          modelData: controlPanel,
          context: this.controller.context,
          params: this.controller.params,
          onControllerAppear: this.onLayoutPanelCreated,
        },
        slots,
      );
    }

    return (
      <div
        class={[
          this.ns.b(),
          this.ns.b(this.typeClass),
          this.ns.m(this.codeName),
          this.sysCssName,
        ]}
      >
        {layoutPanel || this.$slots.default?.()}
      </div>
    );
  },
});
